using System;
using System.Data;
using System.Collections.Generic;

namespace FreeFlow.Administration
{
	/// <summary>
	/// A library published to the database.
	/// </summary>
	public class Library : DatabaseAware, IDeletable
	{
		internal Library(Server server, IDataReader reader) : base(server)
		{
		  name = reader["eProcedureName"].ToString(); 
      lastPublished = (DateTime)reader["eLoadedTime"];
      if (Server.SchemaVersion >= SchemaVersion.Version70)
        procedureCount = Convert.ToInt32(reader["COUNT"]);
		}

    private string name;
    /// <summary>
    /// Gets the name of the library.
    /// </summary>
    public string Name
    {
      get
      {
        return name;
      }
    }

    private DateTime lastPublished;
    /// <summary>
    /// Gets the date and time the library was last published.
    /// </summary>
    public DateTime LastPublished
    {
      get
      {
        return lastPublished;
      }
    }

    private LibraryVersionCollection versions;
    /// <summary>
    /// Gets the versions of the library published to this database.
    /// </summary>
    public LibraryVersionCollection Versions
    {
      get
      {
        if (versions == null)
          versions = new LibraryVersionCollection(Server, Name);
        return versions;
      }
    }

    private List<string> procedures;
    private void ReadProcedures()
    {
      if (procedures == null)
      {
        procedures = new List<string>();
        using (IDataReader reader = Server.ExecuteReader(
          string.Format("SELECT DISTINCT eProcedureName FROM eProcedureLibrary WHERE " +
          "eLibraryName = '{0}' ORDER BY eProcedureName", SqlEscape(name))))
        {
          while (reader.Read())
          {
            procedures.Add(reader["eProcedureName"].ToString());
          }
        }
      }
    }

    private int procedureCount;
    /// <summary>
    /// Gets the number of procedures in which this library is used.
    /// </summary>
    public int ProcedureCount
    {
      get
      {
        if ((procedures == null) && (procedureCount > 0))
          return procedureCount;
        else
        {
          ReadProcedures();
          return procedures.Count;
        }
      }
    }

    /// <summary>
    /// Gets the name of the procedure at the specified index.
    /// </summary>
    /// <param name="index">The index.</param>
    public string Procedure(int index)
    {
      ReadProcedures();
      // it may be the procedure has been deleted since the count was calculated so return null if nothing there
      if ((index >= 0) && (index < procedures.Count))
        return (string)procedures[index];
      else
        return null;
    }

    #region IDeletable Members

    /// <summary>
    /// Deletes this library from the database.
    /// </summary>
    public void Delete()
    {
      Server.ExecuteNonQuery(string.Format("DELETE FROM eProcedure WHERE eProcedureName = '{0}'", name));
    }

    #endregion
  }
}
